home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / asm / adisv1_3.lha / src / opcode_handler_cpu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-24  |  25.2 KB  |  1,174 lines

  1. /*
  2.  * Change history
  3.  * $Log:    opcode_handler_cpu.c,v $
  4.  * Revision 3.0  93/09/24  17:54:12  Martin_Apel
  5.  * New feature: Added extra 68040 FPU opcodes
  6.  * 
  7.  * Revision 2.2  93/07/18  22:56:17  Martin_Apel
  8.  * *** empty log message ***
  9.  * 
  10.  * Revision 2.1  93/07/08  20:48:55  Martin_Apel
  11.  * Minor mod.: Disabled internal error message in non-debugging version
  12.  * 
  13.  * Revision 2.0  93/07/01  11:54:21  Martin_Apel
  14.  * *** empty log message ***
  15.  * 
  16.  * Revision 1.14  93/07/01  11:41:49  Martin_Apel
  17.  * Minor mod.: Now checks for zero upper byte on using CCR
  18.  * 
  19.  * Revision 1.13  93/06/16  20:28:56  Martin_Apel
  20.  * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
  21.  * Minor mod.: Added variables for 68030 / 040 support
  22.  * 
  23.  * Revision 1.12  93/06/06  13:47:17  Martin_Apel
  24.  * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3
  25.  * 
  26.  * Revision 1.11  93/06/03  20:28:42  Martin_Apel
  27.  * Minor mod.: Additional linefeed generation for end instructions has been
  28.  *             moved to format_line
  29.  * 
  30.  * Revision 1.10  93/05/27  20:47:51  Martin_Apel
  31.  * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM
  32.  *          instructions.
  33.  * 
  34.  */
  35.  
  36. #include <string.h>
  37. #include "defs.h"
  38.  
  39. static char rcsid [] = "$Id: opcode_handler_cpu.c,v 3.0 93/09/24 17:54:12 Martin_Apel Exp $";
  40.  
  41. /**********************************************************************/
  42.  
  43. int bit_reg (struct opcode_entry *op)
  44.  
  45. {
  46. if (pass3)
  47.   strcpy (src, reg_names [op->param]);
  48.  
  49. if (MODE_NUM (*code) == 0)         /* data register */
  50.   {
  51.   if (pass3)
  52.     {
  53.     strcat (opcode, ".L");
  54.     strcpy (dest, reg_names [REG_NUM (*code)]);
  55.     }
  56.   return (1);
  57.   }
  58. else
  59.   {
  60.   if (pass3)
  61.     strcat (opcode, ".B");
  62.   return (decode_ea (MODE_NUM (*code), REG_NUM (*code), 
  63.           dest, ACC_BYTE, (short)1) + 1);
  64.   }
  65. }
  66.  
  67. /**********************************************************************/
  68.  
  69. int bit_mem (struct opcode_entry *op)
  70.  
  71. {
  72. if (pass3)
  73.   {
  74.   src [0] = '#';
  75.   format_d (src + 1, (short)*(code + 1), FALSE);
  76.   }
  77.  
  78. if (MODE_NUM (*code) == 0)         /* data register */
  79.   {
  80.   if (pass3)
  81.     {
  82.     strcat (opcode, ".L");
  83.     strcpy (dest, reg_names [REG_NUM (*code)]);
  84.     }
  85.   return (2);
  86.   }
  87. else
  88.   {
  89.   if (pass3)
  90.     strcat (opcode, ".B");
  91.   return (decode_ea (MODE_NUM (*code), REG_NUM(*code), 
  92.           dest, ACC_BYTE, (short)2) + 2);
  93.   }
  94. }
  95.  
  96. /**********************************************************************/
  97.  
  98. int move (struct opcode_entry *op)
  99.  
  100. {
  101. short used;
  102.  
  103. used = decode_ea (MODE_NUM (*code), REG_NUM (*code), src, op->param, (short)1);
  104. used += decode_ea ((short)((*code >> 6) & 0x7), 
  105.                    (short)((*code >> 9) & 0x7), dest, op->param, (short)(used + 1));
  106. return (1 + used);
  107. }
  108.  
  109. /**********************************************************************/
  110.  
  111. int movem (struct opcode_entry *op)
  112.  
  113. {
  114. char *reg_list;
  115. int used;
  116. BOOL incr_list;          /* Reglist starts with D0 in bit 0 */
  117.  
  118.  
  119. if (op->param == MEM)
  120.   {
  121.   /* Transfer registers to memory */
  122.   reg_list = src;
  123.   used = decode_ea (MODE_NUM (*code), REG_NUM (*code), dest,
  124.                     ACC_DATA, (short)2);
  125.   }
  126. else
  127.   {
  128.   reg_list = dest;
  129.   used = decode_ea (MODE_NUM (*code), REG_NUM (*code), src,
  130.                     ACC_DATA, (short)2);
  131.   }
  132.  
  133. incr_list = (MODE_NUM (*code) != 4);         /* predecr mode */
  134.  
  135.  
  136. if (pass3)
  137.   {
  138.   format_reg_list (reg_list, (unsigned short)(*(code + 1)), incr_list, (short)0);
  139.   if (*reg_list == 0)
  140.     {
  141.     /* some compilers generate empty reg lists for movem instructions */
  142.     *reg_list = ' ';
  143.     *(reg_list + 1) = 0;
  144.     }
  145.   }
  146.  
  147. return (2 + used);
  148. }
  149.  
  150. /**********************************************************************/
  151.  
  152. int srccr   (struct opcode_entry *op)
  153.  
  154. {
  155. /* Only possible from ANDI, ORI, EORI */
  156. if (pass3)
  157.   {
  158.   strcpy (opcode, opcode_table [*code >> 6].mnemonic);
  159.   strcpy (dest, special_regs [(*code & 0x0040) ? SR : CCR]);
  160.   /* Check for zero upper byte, if reg == CCR */
  161.   if (!(*code & 0x0040) && (*(code + 1) & 0xff00))
  162.     return (TRANSFER);    
  163.   immed (src, (long)(*(code + 1) & 0xffff));
  164.   }
  165. return (2);
  166. }
  167.  
  168. /**********************************************************************/
  169.  
  170. int special (struct opcode_entry *op)
  171.  
  172. {
  173. /* move usp,     10dxxx
  174.    trap,         00xxxx
  175.    unlk,         011xxx
  176.    link.w        010xxx
  177.  
  178.    reset,        110000
  179.    nop,          110001
  180.    stop,         110010
  181.    rte,          110011
  182.    rtd,          110100
  183.    rts,          110101
  184.    trapv         110110
  185.    rtr,          110111
  186.  
  187.    movec,        11101d
  188. */
  189.  
  190. char *ptr;
  191. int used = 1;
  192.  
  193. if ((*code & 0x38) == 0x30)
  194.   {
  195.   switch (*code & 0xf)
  196.     {
  197.     case 0: ptr = "RESET";
  198.             break;
  199.     case 1: ptr = "NOP";
  200.             break;
  201.     case 2: ptr = "STOP";
  202.             if (pass3)
  203.               immed (src, (long)*(code + 1));
  204.             used = 2;
  205.             break;
  206.     case 3: ptr = "RTE";
  207.             end_instr = TRUE;
  208.             break;
  209.     case 4: if (!mc68020)
  210.               return (TRANSFER);
  211.             ptr = "RTD";
  212.             end_instr = TRUE;
  213.             if (pass3)
  214.               {
  215.               src [0] = '#';
  216.               format_d (src + 1, (short)*(code + 1), FALSE);
  217.               }
  218.             used = 2;
  219.             break;
  220.     case 5: ptr = "RTS";
  221.             end_instr = TRUE;
  222.             break;
  223.     case 6: ptr = "TRAPV";
  224.             break;
  225.     case 7: if (!mc68020)
  226.               return (TRANSFER);
  227.             ptr = "RTR";
  228.             end_instr = TRUE;
  229.             break;
  230.     }
  231.   if (pass3)
  232.     strcpy (opcode, ptr);
  233.   return (used);
  234.   }
  235. else if ((*code & 0x3e) == 0x3a)          /* MOVEC */
  236.   {
  237.   short reg_offset;
  238.  
  239.   if (!mc68020)
  240.     return (TRANSFER);
  241.   switch (*(code + 1) & 0xfff)
  242.     {
  243.     case 0x000: ptr = special_regs [SFC];
  244.                 break;
  245.     case 0x001: ptr = special_regs [DFC];
  246.                 break;
  247.     case 0x002: ptr = special_regs [CACR];
  248.                 break;
  249.     case 0x003: if (mc68040)
  250.                   ptr = special_regs [TC];
  251.                 else
  252.                   return (TRANSFER);
  253.                 break;
  254.     case 0x004: if (mc68040)
  255.                   ptr = special_regs [ITT0];
  256.                 else
  257.                   return (TRANSFER);
  258.                 break;
  259.     case 0x005: if (mc68040)
  260.                   ptr = special_regs [ITT1];
  261.                 else
  262.                   return (TRANSFER);
  263.                 break;
  264.     case 0x006: if (mc68040)
  265.                   ptr = special_regs [DTT0];
  266.                 else
  267.                   return (TRANSFER);
  268.                 break;
  269.     case 0x007: if (mc68040)
  270.                   ptr = special_regs [DTT1];
  271.                 else
  272.                   return (TRANSFER);
  273.                 break;
  274.     case 0x800: ptr = special_regs [USP];
  275.                 break;
  276.     case 0x801: ptr = special_regs [VBR];
  277.                 break;
  278.     case 0x802: ptr = special_regs [CAAR];
  279.                 break;
  280.     case 0x803: ptr = special_regs [MSP];
  281.                 break;
  282.     case 0x804: ptr = special_regs [ISP];
  283.                 break;
  284.     case 0x805: if (mc68040)
  285.                   ptr = special_regs [MMUSR];
  286.                 else
  287.                   return (TRANSFER);
  288.                 break;
  289.     case 0x806: if (mc68040)
  290.                   ptr = special_regs [URP];
  291.                 else
  292.                   return (TRANSFER);
  293.                 break;
  294.     case 0x807: if (mc68040)
  295.                   ptr = special_regs [SRP];
  296.                 else
  297.                   return (TRANSFER);
  298.                 break;
  299.     default : return (TRANSFER);
  300.     }
  301.  
  302.   reg_offset = (*(code + 1) & 0x8000) ? 8 : 0;
  303.   if (pass3)
  304.     {
  305.     strcpy (opcode, "MOVEC.L");
  306.     if (*code & 0x1)
  307.       {
  308.       /* from general register to control register */
  309.       strcpy (dest, ptr);
  310.       strcpy (src, reg_names [((*(code + 1) >> 12) & 0x7) + reg_offset]);
  311.       }
  312.     else
  313.       {
  314.       strcpy (src, ptr);
  315.       strcpy (dest, reg_names [((*(code + 1) >> 12) & 0x7) + reg_offset]);
  316.       }
  317.     }
  318.   return (2);
  319.   }
  320. else if ((*code & 0x30) == 0)
  321.   {
  322.   /* TRAP */
  323.   if (pass3)
  324.     {
  325.     strcpy (opcode, "TRAP");
  326.     src [0] = '#';
  327.     format_d (src + 1, (short)(*code & 0xf), FALSE);
  328.     }
  329.   return (1);
  330.   }
  331. else if ((*code & 0x38) == 0x10)
  332.   {
  333.   /* LINK */
  334.   if (pass3)
  335.     {
  336.     strcpy (opcode, "LINK");
  337.     strcpy (src, reg_names [(*code & 0x7) + 8]);
  338.     dest [0] = '#';
  339.     format_d (dest + 1, (short)*(code + 1), TRUE);
  340.     }
  341.   return (2);
  342.   }
  343. else if ((*code & 0x38) == 0x18)
  344.   {
  345.   /* UNLK */
  346.   if (pass3)
  347.     {
  348.     strcpy (opcode, "UNLK");
  349.     strcpy (src, reg_names [(*code & 0x7) + 8]);
  350.     }
  351.   return (1);
  352.   }
  353. else if ((*code & 0x38) == 0x20)
  354.   {
  355.   if (pass3)
  356.     {
  357.     strcpy (opcode, "MOVE.L");
  358.     strcpy (dest, special_regs [USP]);
  359.     strcpy (src, reg_names [(*code & 0x7) + 8]);
  360.     }
  361.   return (1);
  362.   }
  363. else if ((*code & 0x38) == 0x28)
  364.   {
  365.   if (pass3)
  366.     {
  367.     strcpy (opcode, "MOVE");
  368.     strcpy (src, special_regs [USP]);
  369.     strcpy (dest, reg_names [(*code & 0x7) + 8]);
  370.     }
  371.   return (1);
  372.   }
  373. return (TRANSFER);
  374. }
  375.  
  376. /**********************************************************************/
  377.  
  378. int off_illegal  (struct opcode_entry *op)
  379. /* The official illegal instruction */
  380. {
  381. return (1);
  382. }
  383.  
  384. /**********************************************************************/
  385.  
  386. int illegal  (struct opcode_entry *op)
  387.  
  388. {
  389. src [0] = 0;
  390. dest [0] = 0;
  391. detected_illegal = TRUE;
  392. return (1);
  393. }
  394.  
  395. /**********************************************************************/
  396.  
  397. int immediate (struct opcode_entry *op)
  398.  
  399. {
  400. short used = 2;
  401.  
  402. if (pass2 && op->param == ACC_LONG)
  403.   used = 3;
  404. else
  405.   {
  406.   src [0] = '#';
  407.   switch (op->param)
  408.     {
  409.     case ACC_BYTE:
  410.       format_d (src + 1, (short)(*(code + 1) & 0xff), FALSE);
  411.       break;
  412.     case ACC_WORD:
  413.       format_d (src + 1, (short)*(code + 1), FALSE);
  414.       break;
  415.     case ACC_LONG:
  416.       format_ld (src + 1, ((long)*(code + 1) << 16) + (long)*(code + 2), FALSE);
  417.       used = 3;
  418.       break;
  419.     }
  420.   }
  421. return (decode_ea (MODE_NUM(*code), REG_NUM(*code), dest, op->param, 
  422.                    used) + used);
  423. }
  424.  
  425. /**********************************************************************/
  426.  
  427. int ori_b (struct opcode_entry *op)
  428.  
  429. {
  430. /* Special routine which checks for ORI.B #0,D0 and flags it as
  431.    illegal. This will prevent many unfortunate disassemblies, which
  432.    were meant as data */
  433.  
  434. if (*((ULONG*)code) == 0L)
  435.   {
  436.   detected_illegal = TRUE;
  437.   return (1);
  438.   }
  439. src [0] = '#';
  440. format_d (src + 1, (short)(*(code + 1) & 0xff), FALSE);
  441. return (decode_ea (MODE_NUM(*code), REG_NUM(*code), dest, op->param, (short)2) + 2);
  442. }
  443.  
  444. /**********************************************************************/
  445.  
  446. int single_op (struct opcode_entry *op)
  447.  
  448. {
  449. return (decode_ea (MODE_NUM(*code), REG_NUM(*code), src, op->param,
  450.                    (short)1) + 1);
  451. }
  452.  
  453. /**********************************************************************/
  454.  
  455. int end_single_op (struct opcode_entry *op)
  456. /* A single operand instruction ending an instruction sequence, i.e.
  457.    JMP or RTM */
  458. {
  459. int size;
  460.  
  461. end_instr = TRUE;
  462. size = decode_ea (MODE_NUM(*code), REG_NUM(*code), src, op->param,
  463.                    (short)1) + 1;
  464. return (size);
  465. }
  466.  
  467. /**********************************************************************/
  468.  
  469. int quick (struct opcode_entry *op)
  470.  
  471. {
  472. if (pass3)
  473.   {
  474.   src [0] = '#';
  475.   format_d (src + 1, (short)op->param, TRUE);
  476.   }
  477. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), dest, 
  478.                    (UWORD)(ACC_DATA | (1 << ((*code >> 6) & 0x3))),
  479.                    (short)1) + 1);
  480. /* ((*code >> 6) & 0x3) is the size encoding in the quick instructions.
  481.    It has to be performed, otherwise it would be possible to generate
  482.    instructions, that do e.g. byte accesses do address registers */
  483. }
  484.  
  485. /**********************************************************************/
  486.  
  487. int branch (struct opcode_entry *op)
  488.  
  489. {
  490. long offset;
  491. short used;
  492. unsigned long ref;
  493.  
  494. if ((*code & 0xff) == 0)
  495.   {
  496.   /* word displacement */
  497.   offset = (short)*(code + 1) ;
  498.   used = 2;
  499.   }
  500. else if ((*code & 0xff) == 0xff)
  501.   {
  502.   /* long displacement */
  503.   if (!mc68020)
  504.     return (TRANSFER);
  505.   offset = (*(code + 1) << 16) + *(code + 2);
  506.   used = 3;
  507.   }
  508. else
  509.   {
  510.   /* byte displacement */
  511.   offset = (char)(*code & 0xff);
  512.   used = 1;
  513.   }
  514.  
  515. if (offset & 0x1)
  516.   /* branch to an odd address */
  517.   return (TRANSFER);
  518.  
  519. ref = current_address + 2 + offset;
  520. if (ref < first_address || ref > last_address)
  521.   return (TRANSFER);
  522.  
  523. if (pass3)
  524.   {
  525.   if (gen_label (src, ref, TRUE) == NO_ACCESS && !disasm_quick)
  526.     {
  527. #ifdef DEBUG
  528.     fprintf (stderr, "INTERNAL ERROR: branch: Non-existant label reference during second pass\n");
  529.     fprintf (stderr, "         Current address is: %lx\n", current_address);
  530. #endif
  531.     }
  532.   if (used == 1)
  533.     strcat (opcode, ".S");
  534.   else
  535.     strcat (opcode, ".L");
  536.   }
  537. else
  538.   {
  539.   enter_ref (ref, 0L, ACC_CODE);
  540.   if ((*code & 0xff00) == 0x6000)
  541.     {
  542.     /* unconditional branch */
  543.     end_instr = TRUE;
  544.     }
  545.   }
  546. return (used);
  547. }
  548.  
  549. /**********************************************************************/
  550.  
  551. int dual_op (struct opcode_entry *op)
  552.  
  553. {
  554. if (*code & 0x100)
  555.   {
  556.   /* Data register is source */
  557.   if (pass3)
  558.     strcpy (src, reg_names [op->param]);
  559.   return (decode_ea (MODE_NUM (*code), REG_NUM (*code), dest, 
  560.                      (UWORD)(ACC_DATA | (1 << ((*code >> 6) & 0x3))),
  561.                      (short)1) + 1);
  562.   }
  563. else
  564.   {
  565.   /* Data register is destination */
  566.   if (pass3)
  567.     strcpy (dest, reg_names [op->param]);
  568.   return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, 
  569.                      (UWORD)(ACC_DATA | (1 << ((*code >> 6) & 0x3))),
  570.                      (short)1) + 1);
  571.   }
  572. }
  573.  
  574. /**********************************************************************/
  575.  
  576. int dbranch (struct opcode_entry *op)
  577.  
  578. {
  579. unsigned long ref;
  580.  
  581. if (*(code + 1) & 0x1)
  582.   /* branch to an odd address */
  583.   return (TRANSFER);
  584.  
  585. if (pass3)
  586.   strcpy (src, reg_names [*code & 7]);
  587. ref = current_address + 2 + (short)(*(code + 1));
  588. if (ref < first_address || ref > last_address)
  589.   return (TRANSFER);
  590. if (pass3)
  591.   {
  592.   if (gen_label (dest, ref, TRUE) == NO_ACCESS && !disasm_quick)
  593.     {
  594. #ifdef DEBUG
  595.     fprintf (stderr, "INTERNAL ERROR: dbranch: Non-existant label reference during second pass\n");
  596.     fprintf (stderr, "         Current address is: %lx\n", current_address);
  597. #endif
  598.     }
  599.   }
  600. else
  601.   enter_ref (ref, 0L, ACC_CODE);
  602.  
  603. return (2);
  604. }
  605.  
  606. /**********************************************************************/
  607.  
  608. int shiftreg (struct opcode_entry *op)
  609.  
  610. {
  611. opcode [1] = 'S';
  612. opcode [2] = 0;
  613. switch ((*code >> 3) & 0x3)
  614.   {
  615.   case 0:  /* Arithmetic shift */
  616.            opcode [0] = 'A';
  617.            break;
  618.   case 1:  /* Logical shift */
  619.            opcode [0] = 'L';
  620.            break;
  621.   case 2:  /* Rotate with extend */
  622.            if (pass3)
  623.              strcpy (opcode, "ROX");
  624.            break;
  625.   case 3:  /* Rotate */
  626.            opcode [0] = 'R';
  627.            opcode [1] = 'O';
  628.            break;
  629.   }
  630. if (pass3)
  631.   {
  632.   strcat (opcode, op->mnemonic);
  633.  
  634.   if (*code & 0x20)
  635.     {
  636.     /* shift count is in register */
  637.     strcpy (src, reg_names [op->param & 0x7]);
  638.     /* This is because param gives a shift count of 8, if this bitfield is 0 */
  639.     }
  640.   else
  641.     {
  642.     /* shift count specified as immediate */
  643.     src [0] = '#';
  644.     format_d (src + 1, (short)op->param, FALSE);
  645.     }
  646.  
  647.   strcpy (dest, reg_names [REG_NUM (*code)]);
  648.   }
  649. return (1);
  650. }
  651.  
  652. /**********************************************************************/
  653.  
  654.  
  655. int op_w      (struct opcode_entry *op)
  656.  
  657. {
  658. if (pass3)
  659.   strcpy (dest, reg_names [op->param]);
  660. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, ACC_WORD, 
  661.                    (short) 1) + 1);
  662. }
  663.  
  664. /**********************************************************************/
  665.  
  666. int op_l      (struct opcode_entry *op)
  667.  
  668. {
  669. if (pass3)
  670.   strcpy (dest, reg_names [op->param]);
  671. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, ACC_LONG, 
  672.                    (short) 1) + 1);
  673. }
  674.  
  675. /**********************************************************************/
  676.  
  677. int restrict (struct opcode_entry *op)
  678.  
  679. {
  680. /* For opcodes such as ADDX, SUBX, ABCD, SBCD, PACK, UNPK with only 
  681.    -(Ax) and Dn addressing allowed */
  682. char *tmp;
  683.  
  684. if (pass3)
  685.   {
  686.   if (*code & 0x8)
  687.     {
  688.     /* -(Ax) addressing */
  689.     pre_dec (src, (short)(REG_NUM (*code) + 8));
  690.     pre_dec (dest, (short)(((*code >> 9) & 0x7) + 8));
  691.     }
  692.   else
  693.     {
  694.     /* Dn addressing */
  695.     strcpy (src, reg_names [REG_NUM (*code)]);
  696.     strcpy (dest, reg_names [((*code >> 9) & 0x7)]);
  697.     }
  698.   }
  699.  
  700. if (op->param == NO_ADJ)
  701.   return (1);
  702. else
  703.   {
  704.   if (pass3)
  705.     {
  706.     tmp = dest + strlen (dest);
  707.     *tmp++ = ',';
  708.     immed (tmp, (long)*(code + 1));
  709.     }
  710.   return (2);
  711.   }
  712. }
  713.  
  714. /**********************************************************************/
  715.  
  716. int muldivl (struct opcode_entry *op)
  717.  
  718. {
  719. register short dr, dq;
  720.  
  721. opcode [3] = (*(code + 1) & 0x800) ? 'S' : 'U';
  722. dr = *(code + 1) & 0x7;
  723. dq = (*(code + 1) >> 12) & 0x7;
  724. if (pass3)
  725.   {
  726.   if (*(code + 1) & 0x400)
  727.     {
  728.     /* 64-bit operation */
  729.     strcpy (dest, reg_names [dr]);
  730.     strcat (dest, ":");
  731.     strcat (dest, reg_names [dq]);
  732.     }
  733.   else
  734.     {
  735.     if (dr != dq)
  736.       {
  737.       strcat (opcode, "L");
  738.       strcpy (dest, reg_names [dr]);
  739.       strcat (dest, ":");
  740.       strcat (dest, reg_names [dq]);
  741.       }
  742.     else
  743.       strcpy (dest, reg_names [dq]);
  744.     }
  745.   strcat (opcode, ".L");
  746.   }
  747. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, ACC_LONG,
  748.                    (short)2) + 2);
  749. }
  750.  
  751. /**********************************************************************/
  752.     
  753. int bf_op   (struct opcode_entry *op)
  754.  
  755. {
  756. int used;
  757. short offset, width;
  758. register char *ptr_ea, *ptr_dn;
  759.  
  760. offset = (*(code + 1) >> 6) & 0x1f;
  761. width = *(code + 1) & 0x1f;
  762.  
  763. switch (op->param)
  764.   {
  765.   case SINGLEOP: ptr_ea = src;
  766.                  break;
  767.   case DATADEST: ptr_ea = src;
  768.                  ptr_dn = dest;
  769.                  break;
  770.   case DATASRC : ptr_ea = dest;
  771.                  ptr_dn = src;
  772.                  break;
  773.   }
  774.  
  775. if (pass3)
  776.   {
  777.   if (op->param != SINGLEOP)
  778.     strcpy (ptr_dn, reg_names [(*(code + 1) >> 12) & 0x7]);
  779.   }
  780.  
  781. used = decode_ea (MODE_NUM (*code), REG_NUM (*code), ptr_ea, ACC_DATA,
  782.                   (short)2);
  783.  
  784. if (pass3)
  785.   strcat (ptr_ea, "{");
  786.  
  787. if (*(code + 1) & 0x800)
  788.   {
  789.   /* Offset specified in register */
  790.   if (offset > 7)
  791.     return (TRANSFER);
  792.   if (pass3)
  793.     strcat (ptr_ea, reg_names [offset]);
  794.   }
  795. else if (pass3)
  796.   {
  797.   /* Offset specified as immediate */
  798.   format_d (ptr_ea + strlen (ptr_ea), offset, FALSE);
  799.   }
  800.  
  801. if (pass3)
  802.   strcat (ptr_ea, ":");
  803.  
  804. if (*(code + 1) & 0x20)
  805.   {
  806.   /* Width specified in register */
  807.   if (width > 7)
  808.     return (TRANSFER);
  809.   if (pass3)
  810.     strcat (ptr_ea, reg_names [width]);
  811.   }
  812. else if (pass3)
  813.   {
  814.   /* Width specified as immediate */
  815.   format_d (ptr_ea + strlen (ptr_ea), width, FALSE);
  816.   }
  817.  
  818. if (pass3)
  819.   strcat (ptr_ea, "}");
  820.  
  821. return (2 + used);
  822. }
  823.  
  824. /**********************************************************************/
  825.  
  826. int moveq (struct opcode_entry *op)
  827.  
  828. {
  829. char val;
  830.  
  831. if (pass3)
  832.   {
  833.   src [0] = '#';
  834.   /* Get the sign right */
  835.   val = *code & 0xff;
  836.   format_d (src + 1, (short)val, TRUE);
  837.   strcpy (dest, reg_names [op->param]);
  838.   }
  839. return (1);
  840. }
  841.  
  842. /**********************************************************************/
  843.  
  844. int scc (struct opcode_entry *op)
  845.  
  846. {
  847. if (pass3)
  848.   strcat (opcode, conditions [(*code >> 8) & 0xf]);
  849. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, ACC_BYTE, (short)1)
  850.         + 1);
  851. }
  852.  
  853. /**********************************************************************/
  854.  
  855. int exg  (struct opcode_entry *op)
  856.  
  857. {
  858. short rx = (*code >> REG2_SHIFT) & 0x7;
  859.  
  860. if (((*code >> 3) & 0x1f) == 0x8)
  861.   {
  862.   /* exchange two data registers */
  863.   if (pass3)
  864.     {
  865.     strcpy (src, reg_names [rx]);
  866.     strcpy (dest, reg_names [*code & 0x7]);
  867.     }
  868.   }
  869. else if (((*code >> 3) & 0x1f) == 0x9)
  870.   {
  871.   /* exchange two address registers */
  872.   if (pass3)
  873.     {
  874.     strcpy (src, reg_names [rx + 8]);
  875.     strcpy (dest, reg_names [(*code & 0x7) + 8]);
  876.     }
  877.   }
  878. else if (((*code >> 3) & 0x1f) == 0x11)
  879.   {
  880.   /* exchange an address and a data register */
  881.   if (pass3)
  882.     {
  883.     strcpy (src, reg_names [rx]);
  884.     strcpy (dest, reg_names [(*code & 0x7) + 8]);
  885.     }
  886.   }
  887. else
  888.   return (TRANSFER);
  889. return (1);
  890. }
  891.  
  892. /**********************************************************************/
  893.  
  894. int trapcc (struct opcode_entry *op)
  895.  
  896. {
  897. if (pass3)
  898.   strcat (opcode, conditions [(*code >> 8) & 0xf]);
  899. if ((*code & 0x7) == 2)
  900.   {
  901.   if (pass3)
  902.     immed (src, (long)*(code + 1));
  903.   return (2);
  904.   }
  905. if ((*code & 0x7) == 3)
  906.   {
  907.   if (pass3)
  908.     immed (src, (*(code + 1) << 16) + *(code + 2));
  909.   return (3);
  910.   }
  911.  
  912. return (1);
  913. }
  914.  
  915. /**********************************************************************/
  916.  
  917. int chkcmp2 (struct opcode_entry *op)
  918.  
  919. {
  920. if (pass3)
  921.   {
  922.   if (*(code + 1) & 0x800)
  923.     {
  924.     /* CHK2 */
  925.     opcode [1] = 'H';
  926.     opcode [2] = 'K';
  927.     }
  928.   else
  929.     {
  930.     /* CMP2 */
  931.     opcode [1] = 'M';
  932.     opcode [2] = 'P';
  933.     }
  934.   if (pass3)
  935.     strcpy (dest, reg_names [*(code + 1) >> 12]);
  936.   }
  937. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), src, op->param, (short)2)
  938.         + 2);
  939. }
  940.  
  941. /**********************************************************************/
  942.  
  943. int cas  (struct opcode_entry *op)
  944.  
  945. {
  946. if (pass3)
  947.   {
  948.   strcpy (src, reg_names [*(code + 1) & 0x7]);
  949.   strcat (src, ",");
  950.   strcat (src, reg_names [(*(code + 1) >> 6) & 0x7]);
  951.   }
  952. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), dest, op->param, 
  953.                    (short)2) + 2);
  954. }
  955.  
  956. /**********************************************************************/
  957.  
  958. int cas2 (struct opcode_entry *op)
  959.  
  960. {
  961. if (pass3)
  962.   {
  963.   sprintf (src, "%s:%s,%s:%s", reg_names [*(code + 1) & 0x7],
  964.                                reg_names [*(code + 2) & 0x7],
  965.                                reg_names [(*(code + 1) >> 6) & 0x7],
  966.                                reg_names [(*(code + 2) >> 6) & 0x7]);
  967.  
  968.   sprintf (dest, "(%s):(%s)",  reg_names [*(code + 1) >> 12],
  969.                                reg_names [*(code + 2) >> 12]);
  970.   }
  971. return (3);
  972. }
  973.  
  974. /**********************************************************************/
  975.  
  976. int moves (struct opcode_entry *op)
  977.  
  978. {
  979. char *reg, *ea;
  980.  
  981. if (*(code + 1) & 0x800)
  982.   {
  983.   reg = src;
  984.   ea = dest;
  985.   }
  986. else
  987.   {
  988.   reg = dest;
  989.   ea = src;
  990.   }
  991.  
  992. if (pass3)
  993.   strcpy (reg, reg_names [(*(code + 1) >> 12) & 0xf]);
  994. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), ea, op->param, 
  995.                    (short)2) + 2);
  996. }
  997.  
  998. /**********************************************************************/
  999.  
  1000. int movesrccr (struct opcode_entry *op)
  1001.  
  1002. {
  1003. char *ea;
  1004.  
  1005. if (pass3)
  1006.   {
  1007.   switch (op->param)
  1008.     {
  1009.     case FROM_CCR: strcpy (src, special_regs [CCR]);
  1010.                    ea = dest;
  1011.                    break;
  1012.     case TO_CCR  : strcpy (dest, special_regs [CCR]);
  1013.                    ea = src;
  1014.                    break;
  1015.     case FROM_SR : strcpy (src, special_regs [SR]);
  1016.                    ea = dest;
  1017.                    break;
  1018.     case TO_SR   : strcpy (dest, special_regs [SR]);
  1019.                    ea = src;
  1020.                    break;
  1021.     }
  1022.   }
  1023. return (decode_ea (MODE_NUM (*code), REG_NUM (*code), ea, ACC_WORD, (short)1)
  1024.         + 1);
  1025. }
  1026.  
  1027. /**********************************************************************/
  1028.  
  1029. int cmpm (struct opcode_entry *op)
  1030.  
  1031. {
  1032. if (pass3)
  1033.   {
  1034.   post_inc (src, (short)(*code & 0xf));
  1035.   post_inc (dest, (short)((*code >> 9) & 0xf));
  1036.   }
  1037. return (1);
  1038. }
  1039.  
  1040. /**********************************************************************/
  1041.  
  1042. int movep (struct opcode_entry *op)
  1043.  
  1044. {
  1045. char *dn, *an;
  1046.  
  1047. if (pass3)
  1048.   {
  1049.   if (*code & 0x40)
  1050.     strcat (opcode, ".L");
  1051.   else
  1052.     strcat (opcode, ".W");
  1053.   }
  1054. if (*code & 0x80)
  1055.   {
  1056.   /* Transfer to memory */
  1057.   an = dest;
  1058.   dn = src;
  1059.   }
  1060. else
  1061.   {
  1062.   /* Transfer from memory */
  1063.   an = src;
  1064.   dn =dest;
  1065.   }
  1066.  
  1067. if (pass3)
  1068.   {
  1069.   strcpy (dn, reg_names [(*code >> 9) & 0x7]);
  1070.   disp_an (an, (short)((*code & 0x7) + 8), *(code + 1));
  1071.   }
  1072. return (2);
  1073. }
  1074.  
  1075. /**********************************************************************/
  1076.  
  1077. int bkpt (struct opcode_entry *op)
  1078.  
  1079. {
  1080. if (pass3)
  1081.   {
  1082.   src [0] = '#';
  1083.   format_d (src + 1, (short)(*code & 0x7), FALSE);
  1084.   }
  1085. return (1);
  1086. }
  1087.  
  1088. /**********************************************************************/
  1089.  
  1090. int link_l (struct opcode_entry *op)
  1091.  
  1092. {
  1093. if (pass3)
  1094.   {
  1095.   dest [0] = '#';
  1096.   format_ld (dest + 1, ((long)*(code + 1) << 16) + (long)*(code + 2), FALSE);
  1097.   strcpy (src, reg_names [REG_NUM (*code) + 8]);
  1098.   }
  1099. return (3);
  1100. }
  1101.  
  1102. /**********************************************************************/
  1103.  
  1104. int move16 (struct opcode_entry *op)
  1105.  
  1106. {
  1107. char *tmp;
  1108.  
  1109. if ((*code & 0x20) &&
  1110.     ((*(code + 1) & 0x8fff) == 0x8000))
  1111.   {  /* post increment mode for src and dest */
  1112.   if (pass3)
  1113.     {
  1114.     post_inc (src, (short)((*code & 0x7) + 8));
  1115.     post_inc (dest, (short)(((*(code + 1) >> 12) & 0x7) + 8));
  1116.     }
  1117.   return (2);
  1118.   }
  1119. else if ((*code & 0x20) == 0)
  1120.   {
  1121.   if (pass3)
  1122.     {
  1123.     if (*code & 0x8)    
  1124.       {
  1125.       tmp = dest;
  1126.       decode_ea ((short)7, (short)1, src, (short)(ACC_LONG | ACC_DATA), (short)1);
  1127.       }
  1128.     else
  1129.       {
  1130.       tmp = src;
  1131.       decode_ea ((short)7, (short)1, dest, (short)(ACC_LONG | ACC_DATA), (short)1);
  1132.       }
  1133.     if (*code & 0x10)
  1134.       indirect (tmp, (short)((*code & 0x7) + 8));
  1135.     else
  1136.       post_inc (tmp, (short)((*code & 0x7) + 8));
  1137.     }
  1138.   return (3);
  1139.   }
  1140. return (TRANSFER);
  1141. }
  1142.  
  1143. /**********************************************************************/
  1144.  
  1145. int cache (struct opcode_entry *op)
  1146.  
  1147. {
  1148. if (pass3)
  1149.   {
  1150.   if (*code & 0x20)
  1151.     strcpy (opcode, "CPUSH");
  1152.   else
  1153.     strcpy (opcode, "CINV");
  1154.   switch ((*code >> 3) & 0x3)
  1155.     {
  1156.     case 1: strcat (opcode, "L"); break;
  1157.     case 2: strcat (opcode, "P"); break;
  1158.     case 3: strcat (opcode, "A"); break;
  1159.     }
  1160.  
  1161.   switch (op->param)          /* which cache to modify */
  1162.     {
  1163.     case 0: strcpy (src, "NC"); break;
  1164.     case 1: strcpy (src, "DC"); break;
  1165.     case 2: strcpy (src, "IC"); break;
  1166.     case 3: strcpy (src, "BC"); break;
  1167.     }
  1168.  
  1169.   if (((*code >> 3) & 0x3) != 0x3)      /* not all --> page or line */
  1170.     indirect (dest, (short)(REG_NUM (*code) + 8));
  1171.   }
  1172. return (1);
  1173. }
  1174.